package service

import (
	"context"

	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"

	__ "user_srv/basic/userproto"
	"user_srv/handler/dao"
)

// 财务统计相关接口实现

// GetFinancialStats 获取财务统计数据
func (s *Server) GetFinancialStats(ctx context.Context, req *__.GetFinancialStatsReq) (*__.GetFinancialStatsResp, error) {
	// 验证分组类型
	if req.GroupType < 1 || req.GroupType > 3 {
		return nil, status.Errorf(codes.InvalidArgument, "group_type must be 1 (day), 2 (month), or 3 (year)")
	}

	// 验证并解析日期
	startDate, endDate, err := validateAndParseDates(req.StartDate, req.EndDate)
	if err != nil {
		return nil, err
	}

	// 调用dao层获取数据
	stats, err := dao.GetFinancialStats(ctx, startDate, endDate, int(req.GroupType))
	if err != nil {
		return nil, status.Errorf(codes.Internal, "failed to get financial stats: %v", err)
	}

	// 转换为proto响应格式
	resp := &__.GetFinancialStatsResp{
		Stats: make([]*__.FinancialStats, 0, len(stats)),
	}

	for _, stat := range stats {
		resp.Stats = append(resp.Stats, &__.FinancialStats{
			Date:             stat.Date,
			Income:           stat.Income,
			Expense:          stat.Expense,
			NetIncome:        stat.NetIncome,
			TransactionCount: int32(stat.TransactionCount),
		})
	}

	return resp, nil
}

// GetFinancialSummary 获取财务汇总信息
func (s *Server) GetFinancialSummary(ctx context.Context, req *__.GetFinancialSummaryReq) (*__.GetFinancialSummaryResp, error) {
	// 验证并解析日期
	startDate, endDate, err := validateAndParseDates(req.StartDate, req.EndDate)
	if err != nil {
		return nil, err
	}

	// 调用dao层获取数据
	summary, err := dao.GetFinancialSummary(ctx, startDate, endDate)
	if err != nil {
		return nil, status.Errorf(codes.Internal, "failed to get financial summary: %v", err)
	}

	// 转换为proto响应格式
	return &__.GetFinancialSummaryResp{
		Summary: &__.FinancialSummary{
			TotalIncome:       summary.TotalIncome,
			TotalExpense:      summary.TotalExpense,
			NetIncome:         summary.NetIncome,
			IncomeChangeRate:  summary.IncomeChangeRate,
			ExpenseChangeRate: summary.ExpenseChangeRate,
			NetChangeRate:     summary.NetChangeRate,
			TotalTransactions: int32(summary.TotalTransactions),
		},
	}, nil
}

// GetIncomeBreakdown 获取收入明细
func (s *Server) GetIncomeBreakdown(ctx context.Context, req *__.GetIncomeBreakdownReq) (*__.GetIncomeBreakdownResp, error) {
	// 验证并解析日期
	startDate, endDate, err := validateAndParseDates(req.StartDate, req.EndDate)
	if err != nil {
		return nil, err
	}

	// 规范化分页参数
	page, pageSize := normalizePagination(req.Page, req.PageSize)

	// 调用dao层获取数据
	items, total, err := dao.GetIncomeBreakdown(ctx, startDate, endDate, page, pageSize)
	if err != nil {
		return nil, status.Errorf(codes.Internal, "failed to get income breakdown: %v", err)
	}

	// 转换为proto响应格式
	resp := &__.GetIncomeBreakdownResp{
		Items: make([]*__.IncomeBreakdownItem, 0, len(items)),
		Total: total,
	}

	for _, item := range items {
		resp.Items = append(resp.Items, &__.IncomeBreakdownItem{
			Category:   item.Category,
			Amount:     item.Amount,
			Percentage: item.Percentage,
		})
	}

	return resp, nil
}

// GetExpenseBreakdown 获取支出明细
func (s *Server) GetExpenseBreakdown(ctx context.Context, req *__.GetExpenseBreakdownReq) (*__.GetExpenseBreakdownResp, error) {
	// 验证并解析日期
	startDate, endDate, err := validateAndParseDates(req.StartDate, req.EndDate)
	if err != nil {
		return nil, err
	}

	// 规范化分页参数
	page, pageSize := normalizePagination(req.Page, req.PageSize)

	// 调用dao层获取数据
	items, total, err := dao.GetExpenseBreakdown(ctx, startDate, endDate, page, pageSize)
	if err != nil {
		return nil, status.Errorf(codes.Internal, "failed to get expense breakdown: %v", err)
	}

	// 转换为proto响应格式
	resp := &__.GetExpenseBreakdownResp{
		Items: make([]*__.ExpenseBreakdownItem, 0, len(items)),
		Total: total,
	}

	for _, item := range items {
		resp.Items = append(resp.Items, &__.ExpenseBreakdownItem{
			Category:   item.Category,
			Amount:     item.Amount,
			Percentage: item.Percentage,
		})
	}

	return resp, nil
}

// GetTransactionList 获取交易明细列表
func (s *Server) GetTransactionList(ctx context.Context, req *__.GetTransactionListReq) (*__.GetTransactionListResp, error) {
	// 验证并解析日期
	startDate, endDate, err := validateAndParseDates(req.StartDate, req.EndDate)
	if err != nil {
		return nil, err
	}

	// 验证分页参数
	if req.Pagination == nil {
		return nil, status.Errorf(codes.InvalidArgument, "pagination is required")
	}

	page, pageSize := normalizePagination(req.Pagination.Page, req.Pagination.PageSize)

	// 验证交易类型
	validTypes := map[string]bool{"all": true, "income": true, "expense": true}
	if req.TransactionType != "" && !validTypes[req.TransactionType] {
		return nil, status.Errorf(codes.InvalidArgument, "invalid transaction_type, should be 'all', 'income', or 'expense'")
	}

	// 调用dao层获取数据
	items, total, err := dao.GetTransactionList(ctx, startDate, endDate, req.TransactionType, page, pageSize)
	if err != nil {
		return nil, status.Errorf(codes.Internal, "failed to get transaction list: %v", err)
	}

	// 转换为proto响应格式
	resp := &__.GetTransactionListResp{
		Items: make([]*__.TransactionItem, 0, len(items)),
		Pagination: &__.PaginationResp{
			Total:    total,
			Page:     int32(page),
			PageSize: int32(pageSize),
		},
	}

	for _, item := range items {
		resp.Items = append(resp.Items, &__.TransactionItem{
			Id:              int64(item.ID),
			TransactionTime: item.TransactionTime,
			TransactionType: item.TransactionType,
			Description:     item.Description,
			Amount:          item.Amount,
			PaymentMethod:   item.PaymentMethod,
			Status:          item.Status,
		})
	}

	return resp, nil
}
